/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.Sales;

import entity.Address;
import entity.Customer;
import entity.Job;
import entity.Product;
import entity.PurchaseItem;
import entity.PurchaseOrder;
import entity.Quotation;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import managedbean.UserSessionManagerBean;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import session.stateless.JobSessionBeanLocal;
import session.stateless.LogSessionBeanLocal;
import session.stateless.ProductSessionBeanLocal;

import session.stateless.PurchaseOrderSessionBeanLocal;

/**
 *
 * @author Wx
 */
@ManagedBean(name = "purchaseOrderManagerBean")
@RequestScoped
public class PurchaseOrderManagerBean {

    @ManagedProperty(value = "#{userSessionManagerBean}")
    private UserSessionManagerBean userSessionManagerBean;
    @EJB
    private ProductSessionBeanLocal productSessionBeanLocal;
    @EJB
    private PurchaseOrderSessionBeanLocal purchaseOrderSessionBeanLocal;
    @EJB
    private LogSessionBeanLocal logSessionBeanLocal;
    @EJB
    private JobSessionBeanLocal jobSessionBeanLocal;
    private String loadAddPurchaseOrder;
    private String loadPurchaseItem;
    private Long id;
    private String poNumber;
    private Double totalAmount;
    private Integer leadTime;
    private String status;
    private Date requestDate;
    private Date poDate;
    private String remark;
    private static Address shippingAddress;
    private static Address billingAddress;
    private Address companyAddress;
    private static Customer customer;
    private ArrayList<PurchaseItem> purchaseItems = new ArrayList<PurchaseItem>();
    private ArrayList<Address> shippingAddresses = new ArrayList<Address>();
    private ArrayList<Address> billingAddresses = new ArrayList<Address>();
    private static PurchaseOrder purchaseOrder;
    //PurchaseItem
    private double unitPrice;
    private double subTotal;
    private int quantity;
    private double discount;
    private Product product = new Product();
    private ArrayList<Product> products;
    private int itemsCount;
    private Double creditRate;
    private Double firstPayment;
    private Double cost;
    private Double shippingCost;
    private Double shippingRate;
    private PurchaseItem selectedPurchaseItem;
    private String quotationNumber;
    private ArrayList<String> qNumbers;

    // <editor-fold defaultstate="collapsed" desc="Getter & Setter methods. Click on the + sign on the left to edit the code.">
    /**
     * @return the userSessionManagerBean
     */
    public UserSessionManagerBean getUserSessionManagerBean() {
        return userSessionManagerBean;
    }

    /**
     * @param userSessionManagerBean the userSessionManagerBean to set
     */
    public void setUserSessionManagerBean(UserSessionManagerBean userSessionManagerBean) {
        this.userSessionManagerBean = userSessionManagerBean;
    }

    /**
     * @param loadAddPurchaseOrder the loadAddPurchaseOrder to set
     */
    public void setLoadAddPurchaseOrder(String loadAddPurchaseOrder) {
        this.loadAddPurchaseOrder = loadAddPurchaseOrder;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the totalAmount
     */
    public Double getTotalAmount() {
        return totalAmount;
    }

    /**
     * @param totalAmount the totalAmount to set
     */
    public void setTotalAmount(Double totalAmount) {
        this.totalAmount = totalAmount;
    }

    /**
     * @return the leadTime
     */
    public Integer getLeadTime() {
        return leadTime;
    }

    /**
     * @param leadTime the leadTime to set
     */
    public void setLeadTime(Integer leadTime) {
        this.leadTime = leadTime;
    }

    /**
     * @return the status
     */
    public String getStatus() {
        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(String status) {
        this.status = status;
    }

    /**
     * @return the requestDate
     */
    public Date getRequestDate() {
        return requestDate;
    }

    /**
     * @param requestDate the requestDate to set
     */
    public void setRequestDate(Date requestDate) {
        this.requestDate = requestDate;
    }

    /**
     * @return the remark
     */
    public String getRemark() {
        return remark;
    }

    /**
     * @param remark the remark to set
     */
    public void setRemark(String remark) {
        this.remark = remark;
    }

    /**
     * @return the shippingAddress
     */
    public Address getShippingAddress() {
        return shippingAddress;
    }

    /**
     * @param shippingAddress the shippingAddress to set
     */
    public void setShippingAddress(Address shippingAddress) {
        this.shippingAddress = shippingAddress;
    }

    /**
     * @return the billingAddress
     */
    public Address getBillingAddress() {
        return billingAddress;
    }

    /**
     * @param billingAddress the billingAddress to set
     */
    public void setBillingAddress(Address billingAddress) {
        this.billingAddress = billingAddress;
    }

    /**
     * @return the customer
     */
    public Customer getCustomer() {
        return customer;
    }

    /**
     * @param customer the customer to set
     */
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    /**
     * @return the purchaseItems
     */
    public ArrayList<PurchaseItem> getPurchaseItems() {
        return purchaseItems;
    }

    /**
     * @param purchaseItems the purchaseItems to set
     */
    public void setPurchaseItems(ArrayList<PurchaseItem> purchaseItems) {
        this.purchaseItems = purchaseItems;
    }

    /**
     * @param shippingAddresses the shippingAddresses to set
     */
    public void setShippingAddresses(ArrayList<Address> shippingAddresses) {
        this.shippingAddresses = shippingAddresses;
    }

    /**
     * @param billingAddresses the billingAddresses to set
     */
    public void setBillingAddresses(ArrayList<Address> billingAddresses) {
        this.billingAddresses = billingAddresses;
    }

    /**
     * @return the poNumber
     */
    public String getPoNumber() {
        return poNumber;
    }

    /**
     * @param poNumber the poNumber to set
     */
    public void setPoNumber(String poNumber) {
        this.poNumber = poNumber;
    }

    /**
     * @return the poDate
     */
    public Date getPoDate() {
        return poDate;
    }

    /**
     * @param poDate the poDate to set
     */
    public void setPoDate(Date poDate) {
        this.poDate = poDate;
    }

    /**
     * @return the shippingAddresses
     */
    public ArrayList<Address> getShippingAddresses() {
        return shippingAddresses;
    }

    /**
     * @return the billingAddresses
     */
    public ArrayList<Address> getBillingAddresses() {
        return billingAddresses;
    }

    /**
     * @return the purchaseOrder
     */
    public PurchaseOrder getPurchaseOrder() {
        return purchaseOrder;
    }

    /**
     * @param purchaseOrder the purchaseOrder to set
     */
    public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    /**
     * @return the companyAddress
     */
    public Address getCompanyAddress() {
        return companyAddress;
    }

    /**
     * @param companyAddress the companyAddress to set
     */
    public void setCompanyAddress(Address companyAddress) {
        this.companyAddress = companyAddress;
    }

    /**
     * @param loadPurchaseItem the loadPurchaseItem to set
     */
    public void setLoadPurchaseItem(String loadPurchaseItem) {
        this.loadPurchaseItem = loadPurchaseItem;
    }

    /**
     * @return the unitPrice
     */
    public double getUnitPrice() {
        return unitPrice;
    }

    /**
     * @param unitPrice the unitPrice to set
     */
    public void setUnitPrice(double unitPrice) {
        this.unitPrice = unitPrice;
    }

    /**
     * @return the subTotal
     */
    public double getSubTotal() {
        return subTotal;
    }

    /**
     * @param subTotal the subTotal to set
     */
    public void setSubTotal(double subTotal) {
        this.subTotal = subTotal;
    }

    /**
     * @return the quantity
     */
    public int getQuantity() {
        return quantity;
    }

    /**
     * @param quantity the quantity to set
     */
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    /**
     * @return the discount
     */
    public double getDiscount() {
        return discount;
    }

    /**
     * @param discount the discount to set
     */
    public void setDiscount(double discount) {
        this.discount = discount;
    }

    /**
     * @return the product
     */
    public Product getProduct() {
        return product;
    }

    /**
     * @param product the product to set
     */
    public void setProduct(Product product) {
        this.product = product;
    }

    /**
     * @return the products
     */
    public ArrayList<Product> getProducts() {
        return products;
    }

    /**
     * @param products the products to set
     */
    public void setProducts(ArrayList<Product> products) {
        this.products = products;
    }

    /**
     * @return the itemsCount
     */
    public int getItemsCount() {
        return itemsCount;
    }

    /**
     * @param itemsCount the itemsCount to set
     */
    public void setItemsCount(int itemsCount) {
        this.itemsCount = itemsCount;
    }

    /**
     * @return the creditRate
     */
    public Double getCreditRate() {
        return creditRate;
    }

    /**
     * @param creditRate the creditRate to set
     */
    public void setCreditRate(Double creditRate) {
        this.creditRate = creditRate;
    }

    /**
     * @return the firstPayment
     */
    public Double getFirstPayment() {
        return firstPayment;
    }

    /**
     * @param firstPayment the firstPayment to set
     */
    public void setFirstPayment(Double firstPayment) {
        this.firstPayment = firstPayment;
    }

    /**
     * @return the cost
     */
    public Double getCost() {
        return cost;
    }

    /**
     * @param cost the cost to set
     */
    public void setCost(Double cost) {
        this.cost = cost;
    }

    /**
     * @return the shippingCost
     */
    public Double getShippingCost() {
        return shippingCost;
    }

    /**
     * @param shippingCost the shippingCost to set
     */
    public void setShippingCost(Double shippingCost) {
        this.shippingCost = shippingCost;
    }

    /**
     * @return the selectedPurchaseItem
     */
    public PurchaseItem getSelectedPurchaseItem() {
        return selectedPurchaseItem;
    }

    /**
     * @param selectedPurchaseItem the selectedPurchaseItem to set
     */
    public void setSelectedPurchaseItem(PurchaseItem selectedPurchaseItem) {
        this.selectedPurchaseItem = selectedPurchaseItem;
    }

    /**
     * @return the shippingRate
     */
    public Double getShippingRate() {
        return shippingRate;
    }

    /**
     * @param shippingRate the shippingRate to set
     */
    public void setShippingRate(Double shippingRate) {
        this.shippingRate = shippingRate;
    }

    /**
     * @return the qNumbers
     */
    public ArrayList<String> getqNumbers() {
        return qNumbers;
    }

    /**
     * @param qNumbers the qNumbers to set
     */
    public void setqNumbers(ArrayList<String> qNumbers) {
        this.qNumbers = qNumbers;
    }

    /**
     * @return the quotationNumber
     */
    public String getQuotationNumber() {
        return quotationNumber;
    }

    /**
     * @param quotationNumber the quotationNumber to set
     */
    public void setQuotationNumber(String quotationNumber) {
        this.quotationNumber = quotationNumber;
    }

    //</editor-fold>
    public String getLoadPurchaseItem() {
        setProducts(new ArrayList<Product>(productSessionBeanLocal.getProducts()));
        for (Address o : getCustomer().getAddresses()) {
            if (o.getType().compareTo("Shipping") == 0) {
                getShippingAddresses().add(o);
            }
        }

        refreshOrder();
        
        return null;
    }

    public String getLoadAddPurchaseOrder() {
        try {
            refreshOrder();

            for (Address o : getCustomer().getAddresses()) {
                if (o.getType().compareTo("Billing") == 0) {

                    getBillingAddresses().add(o);
                }
            }
        } catch (Exception exception) {
            try {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + userSessionManagerBean.getServerName() + ":"
                        + userSessionManagerBean.getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=addPurchaseOrder");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        
        return null;
    }

    public void refreshOrder() {
        setPurchaseOrder((PurchaseOrder) getUserSessionManagerBean().getSelectedItem());
        setCustomer(getPurchaseOrder().getCustomer());
        setCompanyAddress(getCustomer().getCompanyAddress());
        setBillingAddress(getPurchaseOrder().getBillingAddress());
        setPoDate(getPurchaseOrder().getPoDate());
        setPoNumber(getPurchaseOrder().getPoNumber());
        setRemark(getPurchaseOrder().getRemark());
        setCreditRate(getPurchaseOrder().getCreditRate());
        setFirstPayment(getPurchaseOrder().getFirstPayment());
        setPurchaseItems(new ArrayList<PurchaseItem>(getPurchaseOrder().getPurchaseItems()));
        
        this.setItemsCount(purchaseItems.size());
        this.setCost(purchaseOrder.getCost());
        this.setShippingCost(purchaseOrder.getShippingCost());
        
        setTotalAmount(getPurchaseOrder().getTotalAmount());

        if (userSessionManagerBean.getSelectedQuotation() != null) {
            quotationNumber = userSessionManagerBean.getSelectedQuotation().getId().toString();
        }
    }

    public void remove(ActionEvent e) {
        try {
            if (selectedPurchaseItem != null) {
                purchaseItems.remove(selectedPurchaseItem);
                purchaseOrder.setPurchaseItems(purchaseItems);

                for (PurchaseItem p : purchaseOrder.getPurchaseItems()) {
                    unitPrice = round(p.getUnitPrice(), 2);
                    discount = round(p.getDiscount(), 2);
                    double actual = 100 - discount;
                    actual = actual / 100;

                    double temp = (p.getQuantity()) / 240;
                    int cases = (p.getQuantity()) / 240;
                    temp -= cases;
                    if (temp != 0) {
                        cases++;
                    }

                    subTotal += ((cases * p.getShippingRate()) + (p.getUnitPrice() * p.getQuantity())) * actual;
                    subTotal = round(subTotal, 2);
                    p.setSubTotal(subTotal);
                }

                double totalcost = 0;
                double totalshipping = 0;
                double total = 0;

                for (PurchaseItem item : ((PurchaseOrder) userSessionManagerBean.getSelectedItem()).getPurchaseItems()) {

                    totalcost += (item.getQuantity() * item.getUnitPrice());
                    int cases = item.getQuantity() / 240;
                    totalshipping += (cases * item.getShippingRate());
                    total += item.getSubTotal();
                }


                for (PurchaseItem item : ((PurchaseOrder) userSessionManagerBean.getSelectedItem()).getPurchaseItems()) {
                    total += item.getSubTotal();
                }
                
                total = round(total, 2);
                totalcost = round(totalcost, 2);
                totalshipping = round(totalshipping, 2);        
                
                purchaseOrder.setTotalAmount(total);
                purchaseOrder.setCost(totalcost);
                purchaseOrder.setShippingCost(totalshipping);
                
                userSessionManagerBean.setSelectedItem(purchaseOrder);
            }

            FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                    + getUserSessionManagerBean().getServerName() + ":"
                    + getUserSessionManagerBean().getServerPort()
                    + "/MerlionERP-war/Web_Sales/purchaseItem.xhtml"); //redirect to quotation.xhtml
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void done(ActionEvent event) {
        userSessionManagerBean.setSelectedItem(purchaseOrder);
        if (purchaseOrder.getPurchaseItems().size() > 0) {
            try {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + userSessionManagerBean.getServerName() + ":"
                        + userSessionManagerBean.getServerPort()
                        + "/MerlionERP-war/Web_Sales/addPurchaseOrder.xhtml");
            } catch (Exception ex) {
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase item cannot be 0.", ""));
        }
    }

    public void addNewPurchaseItem(ActionEvent event) {
        try {
            if (product.getCode() != null) {

                Product p = productSessionBeanLocal.getProduct(product.getCode());

                unitPrice = round(unitPrice, 2);
                discount = round(discount, 2);
                shippingRate = round(shippingRate, 2);

                double actual = 100 - discount;
                actual = actual / 100;

                int cases = quantity / 240;
                if (quantity - (cases * 240) > 0) {
                    cases++;
                }

                subTotal = ((unitPrice * quantity) * actual + (shippingRate * cases));
                subTotal = round(subTotal, 2);

                if (unitPrice > 0 && quantity > 0 && shippingRate > 0) {
                    PurchaseItem poi = new PurchaseItem(unitPrice, shippingRate, subTotal, quantity, discount, p, requestDate, shippingAddress, "Pending", subTotal);

                    purchaseOrder.getPurchaseItems().add(poi);

                    double poTotalAmount = 0;
                    double poSubTotal = 0;
                    double poTotalShipping = 0;

                    for (PurchaseItem item : ((PurchaseOrder) userSessionManagerBean.getSelectedItem()).getPurchaseItems()) {
                        poTotalAmount += item.getSubTotal();

                        int tcases = item.getQuantity() / 240;

                        if (item.getQuantity() - (tcases * 240) > 0) {
                            tcases++;
                        }

                        double tTotalShipping = tcases * item.getShippingRate();

                        poTotalShipping += tTotalShipping;

                        poSubTotal += item.getSubTotal() - tTotalShipping;
                    }

                    poTotalShipping = round(poTotalShipping, 2);
                    poSubTotal = round(poSubTotal, 2);
                    poTotalAmount = round(poTotalAmount, 2);

                    purchaseOrder.setShippingCost(poTotalShipping);
                    purchaseOrder.setCost(poSubTotal);
                    purchaseOrder.setTotalAmount(poTotalAmount);

                    userSessionManagerBean.setSelectedItem(purchaseOrder);

                    FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                            + userSessionManagerBean.getServerName() + ":"
                            + userSessionManagerBean.getServerPort()
                            + "/MerlionERP-war/Web_Sales/purchaseItem.xhtml"); //redirect to quotation.xhtml
                } else {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unit price or quantity cannot be 0.", ""));
                }
            } else {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "A product must be selected.", ""));
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
        }
    }

    public void addPurchaseItem(ActionEvent event) {
        getPurchaseOrder().setBillingAddress(getBillingAddress());
        getPurchaseOrder().setPoNumber(getPoNumber());
        getPurchaseOrder().setRemark(getRemark());
        getPurchaseOrder().setPoDate(getPoDate());
        getPurchaseOrder().setCreditRate(creditRate);
        getPurchaseOrder().setFirstPayment(getFirstPayment());
        
        getUserSessionManagerBean().setSelectedItem(getPurchaseOrder());
        
        userSessionManagerBean.setSelectedQuotation(jobSessionBeanLocal.getQuotation(Long.parseLong(quotationNumber)));

        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                    + getUserSessionManagerBean().getServerName() + ":"
                    + getUserSessionManagerBean().getServerPort()
                    + "/MerlionERP-war/Web_Sales/purchaseItem.xhtml");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void addPurchaseOrder(ActionEvent event) {
        purchaseOrder.setBillingAddress(billingAddress);
        purchaseOrder.setBillingAddress(shippingAddress);

        getPurchaseOrder().setBillingAddress(getBillingAddress());
        getPurchaseOrder().setPoNumber(getPoNumber());
        getPurchaseOrder().setRemark(getRemark());
        getPurchaseOrder().setPoDate(getPoDate());
        getPurchaseOrder().setCreditRate(creditRate);

        if (creditRate == null) {
            creditRate = 0.0;
        }

        purchaseOrder.setCreditRate(creditRate);
        
        totalAmount = purchaseOrder.getCost() + purchaseOrder.getShippingCost();
        firstPayment = (totalAmount * ((100 - purchaseOrder.getCreditRate()) / 100));
        
        totalAmount = round(totalAmount, 2);
        firstPayment = round(firstPayment, 2);
        
        purchaseOrder.setTotalAmount(totalAmount);
        purchaseOrder.setFirstPayment(firstPayment);

        if (purchaseOrder.getBillingAddress() != null && purchaseOrder.getPurchaseItems().size() > 0 && userSessionManagerBean.getSelectedQuotation() != null) {

            Long temp_id = purchaseOrderSessionBeanLocal.addPurchaseOrder(purchaseOrder.getPoNumber(), purchaseOrder.getTotalAmount(),
                    purchaseOrder.getCost(), purchaseOrder.getShippingCost(), purchaseOrder.getStatus(),
                    purchaseOrder.getPoDate(), purchaseOrder.getRemark(), purchaseOrder.getBillingAddress().getId(),
                    purchaseOrder.getCustomer().getCustId(), purchaseOrder.getPurchaseItems(), purchaseOrder.getCreditRate(), purchaseOrder.getFirstPayment());

            Job selectedJob = null;
            for (Job j : jobSessionBeanLocal.getJobs(userSessionManagerBean.getUserId(), true)) {
                System.out.println(j.getJobId());

                for (Quotation q : j.getQuotations()) {

                    if (q.getId() == userSessionManagerBean.getSelectedQuotation().getId()) {
                        selectedJob = j;
                    }
                }
            }
            
            jobSessionBeanLocal.updatePurchaseOrder(selectedJob.getJobId(), temp_id);

            logSessionBeanLocal.addLog("Add purchase order", "Purchase order created: " + purchaseOrder.getPoNumber(), "addPurchaseOrder.xhtml", userSessionManagerBean.getUserId());

            ArrayList<String> al = new ArrayList<String>();
            al.add("Purchase order created");
            al.add("You have successfully created a purchase order record. Please go to proceed to assign the purchase order to the job before proceeding.");
            al.add("Click on the link to return to ");
            al.add("continue");
            al.add("Web_Sales/searchJob.xhtml");
            userSessionManagerBean.setSelectedItem(al);

            try {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/success.xhtml");
            } catch (Exception ex) {
                System.out.println(ex.toString());
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Address or purchase items cannot be 0.", ""));
        }
    }

    public double round(double valueToRound, int numberOfDecimalPlaces) {
        double multiplicationFactor = Math.pow(10, numberOfDecimalPlaces);
        double interestedInZeroDPs = valueToRound * multiplicationFactor;

        return Math.round(interestedInZeroDPs) / multiplicationFactor;
    }

    public List<String> complete(String query) {
        try {
            qNumbers = new ArrayList<String>();

            for (Job j : jobSessionBeanLocal.getJobs()) {
                if (j.getEmployee().getUserId().compareTo(userSessionManagerBean.getUserId()) == 0) {
                    for (Quotation q : j.getQuotations()) {
                        if (q.getStatus().compareTo("Active") == 0) {
                            qNumbers.add(q.getId().toString());
                        }
                    }
                }
            }

            String temp_str = null;
            List<String> matched = new ArrayList<String>();
            
            for (int i = 0; i < qNumbers.size(); i++) {
                temp_str = qNumbers.get(i);
                if (temp_str.startsWith(query)) {
                    matched.add(temp_str);
                }
            }
            
            HashSet hashSet = new HashSet(matched);
            ArrayList<String> temp = new ArrayList(hashSet);
            
            return temp;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        return null;
    }
}